<?php
namespace slinks\core\dependencyInjectionExt\compiler;

use slinks\core\DependencyInjection\ContainerBuilder;
use slinks\core\DependencyInjection\Compiler\PassConfig;

/**
 * Introspects classes and interfaces for all definitions to allow method arguments to be mathced by type.
 *
 * @author navid
 */
class IntrospectTypePass implements ICompilerPass{
    
    /**
     * You can modify the container here before it is dumped to PHP code.
     *
     * @param ContainerBuilder $container
     * @return void
     */
    public function process(ContainerBuilder $container) {
        foreach ($container->getDefinitions() as $definition) {
            
            if ($definition->isSynthetic()) {
                continue;
            }
            
            // add classes and interfaces as tags for type autowiring. 
            if($definition->getFile() != null){
                include_once $definition->getFile();
            }

            if($definition->getClass() != null){
                try{
                    $refClass = new \ReflectionClass($definition->getClass());

                    // add tags for type argument matching. 
                    $definition->addTag($refClass->getName());

                    foreach ($refClass->getInterfaceNames() as $name) {
                        $definition->addTag($name);
                    }
                }catch (\LogicException $e){
                    // TODO: log exception
                } 
            }
            
        }
    }
    
    /**
     * @return the compiler pass type. Such as PassConfig::TYPE_BEFORE_OPTIMIZATION
     */
    public function getType() {
        return PassConfig::TYPE_BEFORE_OPTIMIZATION;
    }
    
}
